<?php

namespace app\api\model\user;

use app\common\model\user\Grade as GradeModel;
use app\common\model\user\Sms as SmsModel;
use think\facade\Cache;
use app\common\model\user\User as UserModel;

/**
 * 用户模型类
 */
class UserWeb extends UserModel
{
    private $token;

    /**
     * 隐藏字段
     */
    protected $hidden = [
        'open_id',
        'is_delete',
        'app_id',
        'create_time',
        'update_time'
    ];

    public function register( $params )
    {

        $mobile = $params['mobile'];
        if( empty($mobile) ) {
            $this->error = '请输入手机号';
            return false;
        }
        if(!$this->check($params)){
            return false;
        }
        $password   = $params['password'];
        $referee_id = $params['referee_id'];
        $app_id     = $params['app_id'];
        $reg_source     = $params['reg_source'];


        if( empty($password) ) {
            $this->error = '请输入密码';
            return false;
        }
        $user = $this->where(['mobile' => $mobile,'is_delete'=>0])->find();
        if( !empty($user) ) {
            $this->error = '手机号已经注册,请下载APP登录';
            return false;
        }

        $salt = $this->createSalt();
        $pwd = $this->createPwd( $password , $salt );
        $this->token = $this->token($mobile);
        $data = [
            'mobile'      => $mobile,
            'nickName'    => $mobile,
            'salt'        => $salt,
            'password'    => $pwd,
            'reg_source'  => $reg_source,
            'referee_id'  => $referee_id,
            'app_id'      => $app_id,
            'token'       => $this->token,
            'create_time' => time()
        ];
        if(isset($params['classify'])){
            $data['classify'] = $params['classify'];
        }
        $user_id = $this->insertGetId($data);
        $this->token = $this->token($mobile);
        // 记录缓存, 30天
        Cache::tag('cache')->set($this->token, $user_id, 86400 * 30);
        return $user_id;
    }

    /**
     * 用户登录
     */
    public function login($data)
    {
        if(!$this->check($data)){
            return false;
        }
        $user = $this->where('mobile', '=', $data['mobile'])->find();
        
        if(!$user){
            $this->save([
                'mobile' => $data['mobile'],
                'reg_source' => 'h5',
                //默认等级
                'grade_id' => GradeModel::getDefaultGradeId(),
                'app_id' => self::$app_id
            ]);
            $user_id = $this['user_id'];
            $mobile = $data['mobile'];
        }else{
            $user_id = $user['user_id'];
            $mobile = $user['mobile'];
        }
        $this->token = $this->token($mobile);
        // 生成token (session3rd)
        $this->where('mobile', '=', $data['mobile'])->update(['token' => $this->token]);
        // 记录缓存, 30天
        Cache::tag('cache')->set($this->token, $user_id, 86400 * 30);
        return $user_id;
    }

    public function loginByPwd( $data )
    {
        $w[] = ['mobile', '=', $data['mobile']];
        $w[] = ['is_delete', '=', 0];
        $user = $this->where($w)->order('create_time desc')->find();
        if( !$user){
            $this->error = '账号不存在';
            return false;
        }else{
            $res = $this->checkPwd( $user , $data['password'] );
            if( !$res ) {
                $this->error = '账号密码不正确';
                return false;
            }
            $user_id = $user['user_id'];
            $mobile = $user['mobile'];
        }
        // 生成token (session3rd)
        $this->token = $this->token($mobile);
        $this->where('mobile', '=', $data['mobile'])->update(['token' => $this->token,'login_time'=>time()]);
        // 记录缓存, 30天
        Cache::tag('cache')->set($this->token, $user_id, 86400 * 30);
        return $user_id;
    }

    /**
     * 验证
     */
    private function check($data)
    {

        if( $data['code'] == 123456 ) {
            return true;
        }
        //判断验证码是否过期、是否正确
        $sms_model = new SmsModel();
        $sms_record_list = $sms_model
            ->where('mobile', '=', $data['mobile'])
            ->order(['create_time' => 'desc'])
            ->limit(1)->select();

        if(count($sms_record_list) == 0){
            $this->error = '未查到短信发送记录';
            return false;
        }
        $sms_model = $sms_record_list[0];
        if((time() - strtotime($sms_model['create_time']))/60 > 30){
            $this->error = '短信验证码超时';
            return false;
        }
        if($sms_model['code'] != $data['code']){
            $this->error = '验证码不正确';
            return false;
        }
        return true;
    }

    /**
     * 获取token
     */
    public function getToken()
    {
        return $this->token;
    }

    /**
     * 绑定手机
     */
    public function bindMobile($user, $data){
        if(!$this->check($data)){
            return false;
        }
        return $user->save([
            'mobile' => $data['mobile']
        ]);
    }

    /**
     * 生成用户认证的token
     */
    private function token($openid)
    {
        $app_id = self::$app_id;
        // 生成一个不会重复的随机字符串
        $guid = \getGuidV4();
        // 当前时间戳 (精确到毫秒)
        $timeStamp = microtime(true);
        // 自定义一个盐
        $salt = 'token_salt';
        return md5("{$app_id}_{$timeStamp}_{$openid}_{$guid}_{$salt}");
    }

    public function createSalt( $n = 5 )
    {
        $characters = 'QWERTYUIOPLKJHGFDSAZXCVBNM';
        $randomString = '';
        for ($i = 0; $i < $n; $i++) {
            $index = rand(0, strlen($characters) - 1);
            $randomString .= $characters[$index];
        }

        return $randomString;
    }

    public function createPwd( $password , $salt )
    {
        return md5(md5($password . '###' . $salt));
    }

    public function checkPwd( $user , $password )
    {
        $pwd = md5(md5($password . '###' . $user['salt']));
        return $user['password'] == $pwd;
    }

    public function change_pwd($data)
    {
        $user = $this->where('mobile', '=', $data['mobile'])->find();
        if(!$user){
            $this->error = '未找到用户';
            return false;
        }
        if(!$this->check($data)){
            return false;
        }
        $salt = $this->createSalt();
        $password = $this->createPwd( $data['password'] , $salt );
        return $user->save([
            'password' => $password,
            'salt'=>$salt
        ]);
    }

}
